#pragma once

#include <string>
#include <vector>
#include <map>
#include <boost/mpl/vector/vector10.hpp>
#include <alpha/utility/datatype.hpp>

namespace alpha { namespace rpc {

template <template <typename> class Tmpl>
struct basic_json: alpha::utility::datatype<basic_json<Tmpl>, Tmpl>
{
	basic_json() {}

	template <typename T>
	basic_json(T const & v): alpha::utility::datatype<basic_json<Tmpl>, Tmpl>(v) {}

	template <typename T>
	basic_json & operator =(T const& v)
	{
		this->assign(v);
		return *this;
	}
};

namespace detail {
	
	template <typename T>
	struct json_tmpl
	{
		typedef struct null { null() {} } null;
		typedef bool boolean;
		typedef double number;
		typedef std::string string;
		typedef std::vector<T> array;
		typedef std::map<std::string, T> object;
		typedef boost::mpl::vector6<null, boolean, number, string, array, object> type;
	};
	
} // namespace detail

typedef basic_json<detail::json_tmpl> json;

}} // namespace alpha::rpc
